{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import os\n",
    "from dotenv import load_dotenv\n",
    "# Load environment variables from openai.env file\n",
    "load_dotenv(\"openai.env\")\n",
    "\n",
    "# Read the OPENAI_API_KEY from the environment\n",
    "api_key = os.getenv(\"OPENAI_API_KEY\")\n",
    "api_base = os.getenv(\"OPENAI_API_BASE\")\n",
    "os.environ[\"OPENAI_API_KEY\"] = api_key\n",
    "os.environ[\"OPENAI_API_BASE\"] = api_base"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "pd.set_option('display.max_row',300)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 几种不同的agent类型\n",
    "- ZERO_SHOT_REACT_DESCRIPTION\n",
    "- CHAT_ZERO_SHOT_REACT_DESCRIPTION\n",
    "- CONVERSATIONAL_REACT_DESCRIPTION\n",
    "- CHAT_CONVERSATIONAL_REACT_DESCRIPTION\n",
    "- OPENAI_FUNCTIONS\n",
    "- STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ZERO_SHOT_REACT_DESCRIPTION\n",
    "零样本增强式生成，即在没有示例的情况下可以自主的进行对话的类型。https://blog.csdn.net/zcyzcyjava/article/details/127006287 [零样本、单样本、少样本]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "verbose=True tags=['zero-shot-react-description'] agent=ZeroShotAgent(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['agent_scratchpad', 'input'], template='Answer the following questions as best you can. You have access to the following tools:\\n\\nSearch: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\\nCalculator: Useful for when you need to answer questions about math.\\n\\nUse the following format:\\n\\nQuestion: the input question you must answer\\nThought: you should always think about what to do\\nAction: the action to take, should be one of [Search, Calculator]\\nAction Input: the input to the action\\nObservation: the result of the action\\n... (this Thought/Action/Action Input/Observation can repeat N times)\\nThought: I now know the final answer\\nFinal Answer: the final answer to the original input question\\n\\nBegin!\\n\\nQuestion: {input}\\nThought:{agent_scratchpad}'), llm=OpenAI(client=<openai.resources.completions.Completions object at 0x11f3994d0>, async_client=<openai.resources.completions.AsyncCompletions object at 0x11f3a4910>, temperature=0.0, openai_api_key='sk-pQ7osw5XrDY1Ejsx99EcEe5f58D04dDeB387B8E6B3C10bDb', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')), output_parser=MRKLOutputParser(), allowed_tools=['Search', 'Calculator']) tools=[Tool(name='Search', description='A search engine. Useful for when you need to answer questions about current events. Input should be a search query.', func=<bound method SerpAPIWrapper.run of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>, coroutine=<bound method SerpAPIWrapper.arun of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>), Tool(name='Calculator', description='Useful for when you need to answer questions about math.', func=<bound method Chain.run of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=OpenAI(client=<openai.resources.completions.Completions object at 0x11f3994d0>, async_client=<openai.resources.completions.AsyncCompletions object at 0x11f3a4910>, temperature=0.0, openai_api_key='sk-pQ7osw5XrDY1Ejsx99EcEe5f58D04dDeB387B8E6B3C10bDb', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>, coroutine=<bound method Chain.arun of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=OpenAI(client=<openai.resources.completions.Completions object at 0x11f3994d0>, async_client=<openai.resources.completions.AsyncCompletions object at 0x11f3a4910>, temperature=0.0, openai_api_key='sk-pQ7osw5XrDY1Ejsx99EcEe5f58D04dDeB387B8E6B3C10bDb', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>)]\n",
      "Answer the following questions as best you can. You have access to the following tools:\n",
      "\n",
      "Search: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\n",
      "Calculator: Useful for when you need to answer questions about math.\n",
      "\n",
      "Use the following format:\n",
      "\n",
      "Question: the input question you must answer\n",
      "Thought: you should always think about what to do\n",
      "Action: the action to take, should be one of [Search, Calculator]\n",
      "Action Input: the input to the action\n",
      "Observation: the result of the action\n",
      "... (this Thought/Action/Action Input/Observation can repeat N times)\n",
      "Thought: I now know the final answer\n",
      "Final Answer: the final answer to the original input question\n",
      "\n",
      "Begin!\n",
      "\n",
      "Question: {input}\n",
      "Thought:{agent_scratchpad}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/tomiezhang/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:117: LangChainDeprecationWarning: The class `langchain_community.llms.openai.OpenAI` was deprecated in langchain-community 0.0.10 and will be removed in 0.2.0. An updated version of the class exists in the langchain-openai package and should be used instead. To use it run `pip install -U langchain-openai` and import as `from langchain_openai import OpenAI`.\n",
      "  warn_deprecated(\n",
      "/Users/tomiezhang/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:117: LangChainDeprecationWarning: The function `initialize_agent` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use Use new agent constructor methods like create_react_agent, create_json_agent, create_structured_chat_agent, etc. instead.\n",
      "  warn_deprecated(\n"
     ]
    }
   ],
   "source": [
    "from langchain.llms import OpenAI\n",
    "from langchain.agents import (\n",
    "    load_tools,\n",
    "    initialize_agent,\n",
    "    AgentType,\n",
    ")\n",
    "import os\n",
    "os.environ[\"SERPAPI_API_KEY\"] = \"f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594\"\n",
    "\n",
    "llm = OpenAI(\n",
    "    temperature=0,\n",
    "    model=\"gpt-3.5-turbo-instruct\",\n",
    ")\n",
    "tools = load_tools([\"serpapi\",\"llm-math\"],llm=llm)\n",
    "agent = initialize_agent(\n",
    "    tools,\n",
    "    llm,\n",
    "    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,\n",
    "    verbose=True,\n",
    ")\n",
    "print(agent)\n",
    "print(agent.agent.llm_chain.prompt.template)\n",
    "#agent.invoke(\"现在美国总统是谁？他的年龄除以2是多少？\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "CHAT_ZERO_SHOT_REACT_DESCRIPTION 使用了chatmodel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/tomiezhang/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:117: LangChainDeprecationWarning: The class `langchain_community.chat_models.openai.ChatOpenAI` was deprecated in langchain-community 0.0.10 and will be removed in 0.2.0. An updated version of the class exists in the langchain-openai package and should be used instead. To use it run `pip install -U langchain-openai` and import as `from langchain_openai import ChatOpenAI`.\n",
      "  warn_deprecated(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "verbose=True tags=['chat-zero-shot-react-description'] agent=ChatAgent(llm_chain=LLMChain(prompt=ChatPromptTemplate(input_variables=['agent_scratchpad', 'input'], messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='Answer the following questions as best you can. You have access to the following tools:\\n\\nSearch: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\\nCalculator: Useful for when you need to answer questions about math.\\n\\nThe way you use the tools is by specifying a json blob.\\nSpecifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\\n\\nThe only values that should be in the \"action\" field are: Search, Calculator\\n\\nThe $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\\n\\n```\\n{{\\n  \"action\": $TOOL_NAME,\\n  \"action_input\": $INPUT\\n}}\\n```\\n\\nALWAYS use the following format:\\n\\nQuestion: the input question you must answer\\nThought: you should always think about what to do\\nAction:\\n```\\n$JSON_BLOB\\n```\\nObservation: the result of the action\\n... (this Thought/Action/Observation can repeat N times)\\nThought: I now know the final answer\\nFinal Answer: the final answer to the original input question\\n\\nBegin! Reminder to always use the exact characters `Final Answer` when responding.')), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['agent_scratchpad', 'input'], template='{input}\\n\\n{agent_scratchpad}'))]), llm=ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x11f3f2990>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x11f4018d0>, temperature=0.0, openai_api_key='sk-pQ7osw5XrDY1Ejsx99EcEe5f58D04dDeB387B8E6B3C10bDb', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')), output_parser=ChatOutputParser(), allowed_tools=['Search', 'Calculator']) tools=[Tool(name='Search', description='A search engine. Useful for when you need to answer questions about current events. Input should be a search query.', func=<bound method SerpAPIWrapper.run of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>, coroutine=<bound method SerpAPIWrapper.arun of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>), Tool(name='Calculator', description='Useful for when you need to answer questions about math.', func=<bound method Chain.run of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x11f3f2990>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x11f4018d0>, temperature=0.0, openai_api_key='sk-pQ7osw5XrDY1Ejsx99EcEe5f58D04dDeB387B8E6B3C10bDb', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>, coroutine=<bound method Chain.arun of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x11f3f2990>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x11f4018d0>, temperature=0.0, openai_api_key='sk-pQ7osw5XrDY1Ejsx99EcEe5f58D04dDeB387B8E6B3C10bDb', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>)]\n",
      "Answer the following questions as best you can. You have access to the following tools:\n",
      "\n",
      "Search: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\n",
      "Calculator: Useful for when you need to answer questions about math.\n",
      "\n",
      "The way you use the tools is by specifying a json blob.\n",
      "Specifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n",
      "\n",
      "The only values that should be in the \"action\" field are: Search, Calculator\n",
      "\n",
      "The $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n",
      "\n",
      "```\n",
      "{{\n",
      "  \"action\": $TOOL_NAME,\n",
      "  \"action_input\": $INPUT\n",
      "}}\n",
      "```\n",
      "\n",
      "ALWAYS use the following format:\n",
      "\n",
      "Question: the input question you must answer\n",
      "Thought: you should always think about what to do\n",
      "Action:\n",
      "```\n",
      "$JSON_BLOB\n",
      "```\n",
      "Observation: the result of the action\n",
      "... (this Thought/Action/Observation can repeat N times)\n",
      "Thought: I now know the final answer\n",
      "Final Answer: the final answer to the original input question\n",
      "\n",
      "Begin! Reminder to always use the exact characters `Final Answer` when responding.\n"
     ]
    }
   ],
   "source": [
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.agents import (\n",
    "    load_tools,\n",
    "    initialize_agent,\n",
    "    AgentType,\n",
    ")\n",
    "import os\n",
    "os.environ[\"SERPAPI_API_KEY\"] = \"f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594\"\n",
    "\n",
    "llm = ChatOpenAI(\n",
    "    temperature=0,\n",
    "    model=\"gpt-3.5-turbo\",\n",
    ")\n",
    "tools = load_tools([\"serpapi\",\"llm-math\"],llm=llm)\n",
    "agent = initialize_agent(\n",
    "    tools,\n",
    "    llm,\n",
    "    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
    "    verbose=True,\n",
    ")\n",
    "print(agent)\n",
    "print(agent.agent.llm_chain.prompt.messages[0].prompt.template)\n",
    "#agent.invoke(\"现在美国总统是谁？他的年龄除以2是多少？\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "CONVERSATIONAL_REACT_DESCRIPTION 一个对话型的agent，这个agent要求与memory一起使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "memory=ConversationBufferMemory(memory_key='chat_history') verbose=True tags=['conversational-react-description'] agent=ConversationalAgent(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['agent_scratchpad', 'chat_history', 'input'], template='Assistant is a large language model trained by OpenAI.\\n\\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\\n\\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\\n\\nOverall, Assistant is a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.\\n\\nTOOLS:\\n------\\n\\nAssistant has access to the following tools:\\n\\n> Search: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\\n> Calculator: Useful for when you need to answer questions about math.\\n\\nTo use a tool, please use the following format:\\n\\n```\\nThought: Do I need to use a tool? Yes\\nAction: the action to take, should be one of [Search, Calculator]\\nAction Input: the input to the action\\nObservation: the result of the action\\n```\\n\\nWhen you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:\\n\\n```\\nThought: Do I need to use a tool? No\\nAI: [your response here]\\n```\\n\\nBegin!\\n\\nPrevious conversation history:\\n{chat_history}\\n\\nNew input: {input}\\n{agent_scratchpad}'), llm=OpenAI(client=<openai.resources.completions.Completions object at 0x11f413590>, async_client=<openai.resources.completions.AsyncCompletions object at 0x11f421010>, temperature=0.0, openai_api_key='sk-pQ7osw5XrDY1Ejsx99EcEe5f58D04dDeB387B8E6B3C10bDb', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')), output_parser=ConvoOutputParser(), allowed_tools=['Search', 'Calculator'], ai_prefix='AI') tools=[Tool(name='Search', description='A search engine. Useful for when you need to answer questions about current events. Input should be a search query.', func=<bound method SerpAPIWrapper.run of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>, coroutine=<bound method SerpAPIWrapper.arun of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>), Tool(name='Calculator', description='Useful for when you need to answer questions about math.', func=<bound method Chain.run of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=OpenAI(client=<openai.resources.completions.Completions object at 0x11f413590>, async_client=<openai.resources.completions.AsyncCompletions object at 0x11f421010>, temperature=0.0, openai_api_key='sk-pQ7osw5XrDY1Ejsx99EcEe5f58D04dDeB387B8E6B3C10bDb', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>, coroutine=<bound method Chain.arun of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=OpenAI(client=<openai.resources.completions.Completions object at 0x11f413590>, async_client=<openai.resources.completions.AsyncCompletions object at 0x11f421010>, temperature=0.0, openai_api_key='sk-pQ7osw5XrDY1Ejsx99EcEe5f58D04dDeB387B8E6B3C10bDb', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>)]\n",
      "Assistant is a large language model trained by OpenAI.\n",
      "\n",
      "Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n",
      "\n",
      "Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n",
      "\n",
      "Overall, Assistant is a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.\n",
      "\n",
      "TOOLS:\n",
      "------\n",
      "\n",
      "Assistant has access to the following tools:\n",
      "\n",
      "> Search: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\n",
      "> Calculator: Useful for when you need to answer questions about math.\n",
      "\n",
      "To use a tool, please use the following format:\n",
      "\n",
      "```\n",
      "Thought: Do I need to use a tool? Yes\n",
      "Action: the action to take, should be one of [Search, Calculator]\n",
      "Action Input: the input to the action\n",
      "Observation: the result of the action\n",
      "```\n",
      "\n",
      "When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:\n",
      "\n",
      "```\n",
      "Thought: Do I need to use a tool? No\n",
      "AI: [your response here]\n",
      "```\n",
      "\n",
      "Begin!\n",
      "\n",
      "Previous conversation history:\n",
      "{chat_history}\n",
      "\n",
      "New input: {input}\n",
      "{agent_scratchpad}\n"
     ]
    }
   ],
   "source": [
    "from langchain.llms import OpenAI\n",
    "from langchain.agents import (\n",
    "    load_tools,\n",
    "    initialize_agent,\n",
    "    AgentType,\n",
    ")\n",
    "from langchain.memory import ConversationBufferMemory\n",
    "import os\n",
    "os.environ[\"SERPAPI_API_KEY\"] = \"f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594\"\n",
    "#记忆组件\n",
    "memory = ConversationBufferMemory(\n",
    "    memory_key=\"chat_history\",\n",
    ")\n",
    "\n",
    "llm = OpenAI(\n",
    "    temperature=0,\n",
    "    model=\"gpt-3.5-turbo-instruct\",\n",
    ")\n",
    "tools = load_tools([\"serpapi\",\"llm-math\"],llm=llm)\n",
    "agent = initialize_agent(\n",
    "    tools,\n",
    "    llm,\n",
    "    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,\n",
    "    memory=memory,#记忆组件\n",
    "    verbose=True,\n",
    ")\n",
    "print(agent)\n",
    "print(agent.agent.llm_chain.prompt.template)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/tomiezhang/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:117: LangChainDeprecationWarning: The function `run` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use invoke instead.\n",
      "  warn_deprecated(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[32;1m\u001b[1;3m\n",
      "AI: Hello Tomie, it's nice to meet you! How can I assist you today?\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\"Hello Tomie, it's nice to meet you! How can I assist you today?\""
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(\"hi i am tomie\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3mThought: Do I need to use a tool? Yes\n",
      "Action: Search\n",
      "Action Input: \"what is my name\"\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m['My Name Is type: Song by Eminem.', 'My Name Is kgmid: /g/1s05n4sxn.', 'My Name Is album: The Slim Shady LP.', 'My Name Is released: 1999.', 'My Name Is artist: Eminem.', 'My Name Is awards: Grammy Award for Best Rap Solo Performance, MTV Video Music Award for Best New Artist.', 'My Name Is genres: Spoken Word, Hip-Hop/Rap.', 'Disney+ is the only place to stream your favorites from Disney, Pixar, Marvel, Star Wars, National Geographic and more.', '\"What\\'s my name? What\\'s my name? Say it louder! Sing along to \"\"What\\'s My Name\"\" with China Anne McClain from Descendants 2 and watch ...', \"REMASTERED IN HD! Get Rihanna's eighth studio album ANTI now: Download on TIDAL: http://smarturl.it/downloadANTI Stream on TIDAL: ...\", 'Disney+ is the only place to stream your favorites from Disney, Pixar, Marvel, Star Wars, National Geographic and more.', '\"What\\'s My Name\" is a song performed by China Anne McClain, Thomas Doherty, and Dylan Playfair that was released as a single on June 2, 2017, by Walt Disney ...', \"Provided to YouTube by Universal Music Group What's My Name · China Anne McClain · Thomas Doherty · Dylan Playfair · Disney Descendants 2 ...\", '\"My Name Is\" is a song by American rapper Eminem from his second album The Slim Shady LP (1999). It is also the opening song and lead single of the album.', 'My Name Is Lyrics · [Produced by Dr. Dre] · Hi, my name is, what? · Hi, my name is, what? · Hi, kids, do you like violence? · Wanna see me stick nine-inch nails ...', 'Official video for \"What\\'s My Name\" by Fivio Foreign & Queen Naija featuring Coi Leray Listen & Download “B.I.B.L.E.” out now: ...']\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m Do I need to use a tool? No\n",
      "AI: Your name is Tomie.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'Your name is Tomie.'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(\"what is my name?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3mThought: Do I need to use a tool? Yes\n",
      "Action: Search\n",
      "Action Input: Thai food recommendations\u001b[0m"
     ]
    },
    {
     "ename": "ValueError",
     "evalue": "Got error from SerpAPI: Your account has run out of searches.",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[8], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43magent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m有什么好吃的泰国菜可以推荐给我吗?\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:145\u001b[0m, in \u001b[0;36mdeprecated.<locals>.deprecate.<locals>.warning_emitting_wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m    143\u001b[0m     warned \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m    144\u001b[0m     emit_warning()\n\u001b[0;32m--> 145\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mwrapped\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain/chains/base.py:545\u001b[0m, in \u001b[0;36mChain.run\u001b[0;34m(self, callbacks, tags, metadata, *args, **kwargs)\u001b[0m\n\u001b[1;32m    543\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(args) \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m    544\u001b[0m         \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`run` supports only one positional argument.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 545\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43margs\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmetadata\u001b[49m\u001b[43m)\u001b[49m[\n\u001b[1;32m    546\u001b[0m         _output_key\n\u001b[1;32m    547\u001b[0m     ]\n\u001b[1;32m    549\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m kwargs \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[1;32m    550\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m(kwargs, callbacks\u001b[38;5;241m=\u001b[39mcallbacks, tags\u001b[38;5;241m=\u001b[39mtags, metadata\u001b[38;5;241m=\u001b[39mmetadata)[\n\u001b[1;32m    551\u001b[0m         _output_key\n\u001b[1;32m    552\u001b[0m     ]\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:145\u001b[0m, in \u001b[0;36mdeprecated.<locals>.deprecate.<locals>.warning_emitting_wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m    143\u001b[0m     warned \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m    144\u001b[0m     emit_warning()\n\u001b[0;32m--> 145\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mwrapped\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain/chains/base.py:378\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs, callbacks, tags, metadata, run_name, include_run_info)\u001b[0m\n\u001b[1;32m    346\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Execute the chain.\u001b[39;00m\n\u001b[1;32m    347\u001b[0m \n\u001b[1;32m    348\u001b[0m \u001b[38;5;124;03mArgs:\u001b[39;00m\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    369\u001b[0m \u001b[38;5;124;03m        `Chain.output_keys`.\u001b[39;00m\n\u001b[1;32m    370\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m    371\u001b[0m config \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m    372\u001b[0m     \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcallbacks\u001b[39m\u001b[38;5;124m\"\u001b[39m: callbacks,\n\u001b[1;32m    373\u001b[0m     \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtags\u001b[39m\u001b[38;5;124m\"\u001b[39m: tags,\n\u001b[1;32m    374\u001b[0m     \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmetadata\u001b[39m\u001b[38;5;124m\"\u001b[39m: metadata,\n\u001b[1;32m    375\u001b[0m     \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_name\u001b[39m\u001b[38;5;124m\"\u001b[39m: run_name,\n\u001b[1;32m    376\u001b[0m }\n\u001b[0;32m--> 378\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    379\u001b[0m \u001b[43m    \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    380\u001b[0m \u001b[43m    \u001b[49m\u001b[43mcast\u001b[49m\u001b[43m(\u001b[49m\u001b[43mRunnableConfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[43mk\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mk\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mis\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    381\u001b[0m \u001b[43m    \u001b[49m\u001b[43mreturn_only_outputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreturn_only_outputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    382\u001b[0m \u001b[43m    \u001b[49m\u001b[43minclude_run_info\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minclude_run_info\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    383\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain/chains/base.py:163\u001b[0m, in \u001b[0;36mChain.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m    161\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m    162\u001b[0m     run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n\u001b[0;32m--> 163\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m    164\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_end(outputs)\n\u001b[1;32m    166\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m include_run_info:\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain/chains/base.py:153\u001b[0m, in \u001b[0;36mChain.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m    150\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m    151\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_validate_inputs(inputs)\n\u001b[1;32m    152\u001b[0m     outputs \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m--> 153\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    154\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[1;32m    155\u001b[0m         \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call(inputs)\n\u001b[1;32m    156\u001b[0m     )\n\u001b[1;32m    158\u001b[0m     final_outputs: Dict[\u001b[38;5;28mstr\u001b[39m, Any] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprep_outputs(\n\u001b[1;32m    159\u001b[0m         inputs, outputs, return_only_outputs\n\u001b[1;32m    160\u001b[0m     )\n\u001b[1;32m    161\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain/agents/agent.py:1432\u001b[0m, in \u001b[0;36mAgentExecutor._call\u001b[0;34m(self, inputs, run_manager)\u001b[0m\n\u001b[1;32m   1430\u001b[0m \u001b[38;5;66;03m# We now enter the agent loop (until it returns something).\u001b[39;00m\n\u001b[1;32m   1431\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_continue(iterations, time_elapsed):\n\u001b[0;32m-> 1432\u001b[0m     next_step_output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_take_next_step\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1433\u001b[0m \u001b[43m        \u001b[49m\u001b[43mname_to_tool_map\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1434\u001b[0m \u001b[43m        \u001b[49m\u001b[43mcolor_mapping\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1435\u001b[0m \u001b[43m        \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1436\u001b[0m \u001b[43m        \u001b[49m\u001b[43mintermediate_steps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1437\u001b[0m \u001b[43m        \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1438\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1439\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(next_step_output, AgentFinish):\n\u001b[1;32m   1440\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_return(\n\u001b[1;32m   1441\u001b[0m             next_step_output, intermediate_steps, run_manager\u001b[38;5;241m=\u001b[39mrun_manager\n\u001b[1;32m   1442\u001b[0m         )\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain/agents/agent.py:1138\u001b[0m, in \u001b[0;36mAgentExecutor._take_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m   1129\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_take_next_step\u001b[39m(\n\u001b[1;32m   1130\u001b[0m     \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m   1131\u001b[0m     name_to_tool_map: Dict[\u001b[38;5;28mstr\u001b[39m, BaseTool],\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m   1135\u001b[0m     run_manager: Optional[CallbackManagerForChainRun] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m   1136\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Union[AgentFinish, List[Tuple[AgentAction, \u001b[38;5;28mstr\u001b[39m]]]:\n\u001b[1;32m   1137\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_consume_next_step(\n\u001b[0;32m-> 1138\u001b[0m         \u001b[43m[\u001b[49m\n\u001b[1;32m   1139\u001b[0m \u001b[43m            \u001b[49m\u001b[43ma\u001b[49m\n\u001b[1;32m   1140\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_iter_next_step\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1141\u001b[0m \u001b[43m                \u001b[49m\u001b[43mname_to_tool_map\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1142\u001b[0m \u001b[43m                \u001b[49m\u001b[43mcolor_mapping\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1143\u001b[0m \u001b[43m                \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1144\u001b[0m \u001b[43m                \u001b[49m\u001b[43mintermediate_steps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1145\u001b[0m \u001b[43m                \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1146\u001b[0m \u001b[43m            \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1147\u001b[0m \u001b[43m        \u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m   1148\u001b[0m     )\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain/agents/agent.py:1138\u001b[0m, in \u001b[0;36m<listcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m   1129\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_take_next_step\u001b[39m(\n\u001b[1;32m   1130\u001b[0m     \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m   1131\u001b[0m     name_to_tool_map: Dict[\u001b[38;5;28mstr\u001b[39m, BaseTool],\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m   1135\u001b[0m     run_manager: Optional[CallbackManagerForChainRun] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m   1136\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Union[AgentFinish, List[Tuple[AgentAction, \u001b[38;5;28mstr\u001b[39m]]]:\n\u001b[1;32m   1137\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_consume_next_step(\n\u001b[0;32m-> 1138\u001b[0m         \u001b[43m[\u001b[49m\n\u001b[1;32m   1139\u001b[0m \u001b[43m            \u001b[49m\u001b[43ma\u001b[49m\n\u001b[1;32m   1140\u001b[0m \u001b[43m            \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_iter_next_step\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1141\u001b[0m \u001b[43m                \u001b[49m\u001b[43mname_to_tool_map\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1142\u001b[0m \u001b[43m                \u001b[49m\u001b[43mcolor_mapping\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1143\u001b[0m \u001b[43m                \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1144\u001b[0m \u001b[43m                \u001b[49m\u001b[43mintermediate_steps\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1145\u001b[0m \u001b[43m                \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1146\u001b[0m \u001b[43m            \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1147\u001b[0m \u001b[43m        \u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m   1148\u001b[0m     )\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain/agents/agent.py:1223\u001b[0m, in \u001b[0;36mAgentExecutor._iter_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m   1221\u001b[0m     \u001b[38;5;28;01myield\u001b[39;00m agent_action\n\u001b[1;32m   1222\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m agent_action \u001b[38;5;129;01min\u001b[39;00m actions:\n\u001b[0;32m-> 1223\u001b[0m     \u001b[38;5;28;01myield\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_perform_agent_action\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1224\u001b[0m \u001b[43m        \u001b[49m\u001b[43mname_to_tool_map\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcolor_mapping\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43magent_action\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\n\u001b[1;32m   1225\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain/agents/agent.py:1245\u001b[0m, in \u001b[0;36mAgentExecutor._perform_agent_action\u001b[0;34m(self, name_to_tool_map, color_mapping, agent_action, run_manager)\u001b[0m\n\u001b[1;32m   1243\u001b[0m         tool_run_kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mllm_prefix\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m   1244\u001b[0m     \u001b[38;5;66;03m# We then call the tool on the tool input to get an observation\u001b[39;00m\n\u001b[0;32m-> 1245\u001b[0m     observation \u001b[38;5;241m=\u001b[39m \u001b[43mtool\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m   1246\u001b[0m \u001b[43m        \u001b[49m\u001b[43magent_action\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtool_input\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1247\u001b[0m \u001b[43m        \u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1248\u001b[0m \u001b[43m        \u001b[49m\u001b[43mcolor\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcolor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1249\u001b[0m \u001b[43m        \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m   1250\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mtool_run_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m   1251\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1252\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m   1253\u001b[0m     tool_run_kwargs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39magent\u001b[38;5;241m.\u001b[39mtool_run_logging_kwargs()\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/tools.py:417\u001b[0m, in \u001b[0;36mBaseTool.run\u001b[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, **kwargs)\u001b[0m\n\u001b[1;32m    415\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mException\u001b[39;00m, \u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m    416\u001b[0m     run_manager\u001b[38;5;241m.\u001b[39mon_tool_error(e)\n\u001b[0;32m--> 417\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m    418\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    419\u001b[0m     run_manager\u001b[38;5;241m.\u001b[39mon_tool_end(observation, color\u001b[38;5;241m=\u001b[39mcolor, name\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/tools.py:376\u001b[0m, in \u001b[0;36mBaseTool.run\u001b[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, **kwargs)\u001b[0m\n\u001b[1;32m    373\u001b[0m     parsed_input \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_parse_input(tool_input)\n\u001b[1;32m    374\u001b[0m     tool_args, tool_kwargs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_to_args_and_kwargs(parsed_input)\n\u001b[1;32m    375\u001b[0m     observation \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m--> 376\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mtool_args\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mtool_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    377\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[1;32m    378\u001b[0m         \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run(\u001b[38;5;241m*\u001b[39mtool_args, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mtool_kwargs)\n\u001b[1;32m    379\u001b[0m     )\n\u001b[1;32m    380\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m ValidationError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m    381\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandle_validation_error:\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/tools.py:580\u001b[0m, in \u001b[0;36mTool._run\u001b[0;34m(self, run_manager, *args, **kwargs)\u001b[0m\n\u001b[1;32m    571\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfunc:\n\u001b[1;32m    572\u001b[0m     new_argument_supported \u001b[38;5;241m=\u001b[39m signature(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfunc)\u001b[38;5;241m.\u001b[39mparameters\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcallbacks\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m    573\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m (\n\u001b[1;32m    574\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfunc(\n\u001b[1;32m    575\u001b[0m             \u001b[38;5;241m*\u001b[39margs,\n\u001b[1;32m    576\u001b[0m             callbacks\u001b[38;5;241m=\u001b[39mrun_manager\u001b[38;5;241m.\u001b[39mget_child() \u001b[38;5;28;01mif\u001b[39;00m run_manager \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m    577\u001b[0m             \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[1;32m    578\u001b[0m         )\n\u001b[1;32m    579\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m new_argument_supported\n\u001b[0;32m--> 580\u001b[0m         \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    581\u001b[0m     )\n\u001b[1;32m    582\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTool does not support sync\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_community/utilities/serpapi.py:84\u001b[0m, in \u001b[0;36mSerpAPIWrapper.run\u001b[0;34m(self, query, **kwargs)\u001b[0m\n\u001b[1;32m     82\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mrun\u001b[39m(\u001b[38;5;28mself\u001b[39m, query: \u001b[38;5;28mstr\u001b[39m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28mstr\u001b[39m:\n\u001b[1;32m     83\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"Run query through SerpAPI and parse result.\"\"\"\u001b[39;00m\n\u001b[0;32m---> 84\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_process_response\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mresults\u001b[49m\u001b[43m(\u001b[49m\u001b[43mquery\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_community/utilities/serpapi.py:130\u001b[0m, in \u001b[0;36mSerpAPIWrapper._process_response\u001b[0;34m(res)\u001b[0m\n\u001b[1;32m    128\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Process response from SerpAPI.\"\"\"\u001b[39;00m\n\u001b[1;32m    129\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124merror\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m res\u001b[38;5;241m.\u001b[39mkeys():\n\u001b[0;32m--> 130\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGot error from SerpAPI: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mres[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124merror\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m    131\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124manswer_box_list\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m res\u001b[38;5;241m.\u001b[39mkeys():\n\u001b[1;32m    132\u001b[0m     res[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124manswer_box\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m res[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124manswer_box_list\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n",
      "\u001b[0;31mValueError\u001b[0m: Got error from SerpAPI: Your account has run out of searches."
     ]
    }
   ],
   "source": [
    "agent.run(\"有什么好吃的泰国菜可以推荐给我吗?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3mThought: Do I need to use a tool? Yes\n",
      "Action: Search\n",
      "Action Input: \"What is the last letter of my name?\" and \"Who won the 1998 World Cup?\"\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m['The final was held on 12 July 1998 at the Stade de France, Saint-Denis. France defeated holders Brazil 3–0, with two goals from Zinedine Zidane and a stoppage ...', 'Here is every World Cup winner, runner up and third place team dating back to the first tournament in 1930.', \"Zidane was named the man of the match, while Ronaldo was awarded the Golden Ball as FIFA's outstanding player of the tournament. Following the win, hundreds of ...\", 'Take a look through history at each of the first 20 World Cup champions.', \"Over the course of history, only one host had reached the final and not won the match – that was Brazil in 1950. Since the World Cup's inception ...\", 'Staging the World Cup for the second time, France reached their first Final, against four-time champions and hot favourites Brazil no less.', 'Full list of World Cup winners: URUGUAY 1930 - URUGUAY. Uruguay won the inaugural FIFA World Cup after beating Argentina 4-2 in the final in ...', 'All the highlights from the famous Final at the 1998 FIFA World Cup France™, which featured two Zinedine Zidane goals in a surprising French ...', 'The name came from \"Football\", with the \"-ix\" suffix originating from the popular comic strip \"Astérix\" in which the Gauls (precursors of the French people), ...', 'Argentina have been crowned World Cup champions after beating holders France in a penalty shootout, as Qatar hosted the most memorable final ...']\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m Do I need to use a tool? No\n",
      "AI: The last letter of your name is \"e\". And the winner of the 1998 World Cup was France.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'The last letter of your name is \"e\". And the winner of the 1998 World Cup was France.'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(\"这些我都没吃过！我名字的最后一个字母是什么？1998年的世界杯谁夺冠了？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3mThought: Do I need to use a tool? Yes\n",
      "Action: Search\n",
      "Action Input: What is the current temperature in Xi'an, Shaanxi, China?\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m{'type': 'weather_result', 'temperature': '31', 'unit': 'Fahrenheit', 'precipitation': '0%', 'humidity': '94%', 'wind': '2 mph', 'location': \"Xi'An, Shaanxi, China\", 'date': 'Wednesday 10:00 PM', 'weather': 'Mostly cloudy'}\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m Do I need to use a tool? Yes\n",
      "Action: Search\n",
      "Action Input: What have we talked about so far?\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m[\"As asked by you, the correct sentence is “we did talk”. The concept for this is we don't use second form of verb with “did”. We mostly use it ...\", \"... I run out of oxygen When I run away to Mars I can't tell which way's home I've been gone for so long It's an empty world Up here I skip ...\", 'High quality example sentences with “we have discussed so far” in context from reliable sources - Ludwig is the linguistic search engine that helps you to ...', \"So far, we've talked about how companions need to understand both the past and the future in order to be effective.\", \"Someone who needed to hear, “it's not always about you, so shut up” far too many times. Someone who never cared to realize that people offering ...\", '... discussed the research ethics lessons that we have learned so far in the COVID-19 context. Invited panelists: -Sandra Tapia (President of ...', 'UChicago professor and leading psychologist, Katherine Kinzler, explains how speech creates and deepens social biases.', '\"How are you?\" is an overused phrase that leads to meaningless small talk, says happiness and relationship expert Stephanie Harrison.', 'Thinking about asking \"What are we?\" Few questions are more terrifying. The \"are we dating\" talk gives us all anxiety. Discover 11 tips from ...', \"... they're convinced we are too far gone. For all their wealth and power, they don't believe they can affect the future. They are simply ...\"]\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m Do I need to use a tool? No\n",
      "AI: We have talked about a variety of topics, including your name, Thai food recommendations, the current temperature in Xi'an, and the winner of the 1998 World Cup. Is there anything else you would like to discuss?\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\"We have talked about a variety of topics, including your name, Thai food recommendations, the current temperature in Xi'an, and the winner of the 1998 World Cup. Is there anything else you would like to discuss?\""
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(\"中国陕西西安现在的气温多少？截止目前我们聊了什么？\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "CHAT_CONVERSATIONAL_REACT_DESCRIPTION 使用了chatmodel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "memory=ConversationBufferMemory(return_messages=True, memory_key='chat_history') verbose=True tags=['chat-conversational-react-description'] agent=ConversationalChatAgent(llm_chain=LLMChain(prompt=ChatPromptTemplate(input_variables=['agent_scratchpad', 'chat_history', 'input'], input_types={'chat_history': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]], 'agent_scratchpad': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]]}, messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='Assistant is a large language model trained by OpenAI.\\n\\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\\n\\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\\n\\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.')), MessagesPlaceholder(variable_name='chat_history'), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='TOOLS\\n------\\nAssistant can ask the user to use tools to look up information that may be helpful in answering the users original question. The tools the human can use are:\\n\\n> Search: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\\n> Calculator: Useful for when you need to answer questions about math.\\n\\nRESPONSE FORMAT INSTRUCTIONS\\n----------------------------\\n\\nWhen responding to me, please output a response in one of two formats:\\n\\n**Option 1:**\\nUse this if you want the human to use a tool.\\nMarkdown code snippet formatted in the following schema:\\n\\n```json\\n{{\\n    \"action\": string, \\\\\\\\ The action to take. Must be one of Search, Calculator\\n    \"action_input\": string \\\\\\\\ The input to the action\\n}}\\n```\\n\\n**Option #2:**\\nUse this if you want to respond directly to the human. Markdown code snippet formatted in the following schema:\\n\\n```json\\n{{\\n    \"action\": \"Final Answer\",\\n    \"action_input\": string \\\\\\\\ You should put what you want to return to use here\\n}}\\n```\\n\\nUSER\\'S INPUT\\n--------------------\\nHere is the user\\'s input (remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else):\\n\\n{input}')), MessagesPlaceholder(variable_name='agent_scratchpad')]), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')), output_parser=ConvoOutputParser(), allowed_tools=['Search', 'Calculator'], template_tool_response=\"TOOL RESPONSE: \\n---------------------\\n{observation}\\n\\nUSER'S INPUT\\n--------------------\\n\\nOkay, so what is the response to my last comment? If using information obtained from the tools you must mention it explicitly without mentioning the tool names - I have forgotten all TOOL RESPONSES! Remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else.\") tools=[Tool(name='Search', description='A search engine. Useful for when you need to answer questions about current events. Input should be a search query.', func=<bound method SerpAPIWrapper.run of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>, coroutine=<bound method SerpAPIWrapper.arun of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>), Tool(name='Calculator', description='Useful for when you need to answer questions about math.', func=<bound method Chain.run of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>, coroutine=<bound method Chain.arun of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>)]\n",
      "Assistant is a large language model trained by OpenAI.\n",
      "\n",
      "Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n",
      "\n",
      "Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n",
      "\n",
      "Overall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.\n",
      "TOOLS\n",
      "------\n",
      "Assistant can ask the user to use tools to look up information that may be helpful in answering the users original question. The tools the human can use are:\n",
      "\n",
      "> Search: A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\n",
      "> Calculator: Useful for when you need to answer questions about math.\n",
      "\n",
      "RESPONSE FORMAT INSTRUCTIONS\n",
      "----------------------------\n",
      "\n",
      "When responding to me, please output a response in one of two formats:\n",
      "\n",
      "**Option 1:**\n",
      "Use this if you want the human to use a tool.\n",
      "Markdown code snippet formatted in the following schema:\n",
      "\n",
      "```json\n",
      "{{\n",
      "    \"action\": string, \\\\ The action to take. Must be one of Search, Calculator\n",
      "    \"action_input\": string \\\\ The input to the action\n",
      "}}\n",
      "```\n",
      "\n",
      "**Option #2:**\n",
      "Use this if you want to respond directly to the human. Markdown code snippet formatted in the following schema:\n",
      "\n",
      "```json\n",
      "{{\n",
      "    \"action\": \"Final Answer\",\n",
      "    \"action_input\": string \\\\ You should put what you want to return to use here\n",
      "}}\n",
      "```\n",
      "\n",
      "USER'S INPUT\n",
      "--------------------\n",
      "Here is the user's input (remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else):\n",
      "\n",
      "{input}\n",
      "variable_name='agent_scratchpad'\n"
     ]
    }
   ],
   "source": [
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.agents import (\n",
    "    load_tools,\n",
    "    initialize_agent,\n",
    "    AgentType,\n",
    ")\n",
    "from langchain.memory import ConversationBufferMemory\n",
    "import os\n",
    "os.environ[\"SERPAPI_API_KEY\"] = \"f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594\"\n",
    "#记忆组件\n",
    "memory = ConversationBufferMemory(\n",
    "    memory_key=\"chat_history\",\n",
    "    return_messages=True,\n",
    ")\n",
    "\n",
    "llm = ChatOpenAI(\n",
    "    temperature=0,\n",
    "    model=\"gpt-4-1106-preview\",\n",
    ")\n",
    "tools = load_tools([\"serpapi\",\"llm-math\"],llm=llm)\n",
    "agent = initialize_agent(\n",
    "    tools,\n",
    "    llm,\n",
    "    agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,\n",
    "    memory=memory,#记忆组件\n",
    "    verbose=True,\n",
    ")\n",
    "print(agent)\n",
    "print(agent.agent.llm_chain.prompt.messages[0].prompt.template)\n",
    "print(agent.agent.llm_chain.prompt.messages[2].prompt.template)\n",
    "print(agent.agent.llm_chain.prompt.messages[3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m```json\n",
      "{\n",
      "    \"action\": \"Final Answer\",\n",
      "    \"action_input\": \"Hello Tony, how can I assist you today?\"\n",
      "}\n",
      "```\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'Hello Tony, how can I assist you today?'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(input=\"hi i am tony\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m```json\n",
      "{\n",
      "    \"action\": \"Final Answer\",\n",
      "    \"action_input\": \"Your name is Tony.\"\n",
      "}\n",
      "```\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'Your name is Tony.'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(input=\"what is my name?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m```json\n",
      "{\n",
      "    \"action\": \"Search\",\n",
      "    \"action_input\": \"推荐的泰国菜\"\n",
      "}\n",
      "```\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m['要说到泰菜里面Vivian最喜欢的一定要属菠萝炒饭啦！泰国香米的香气，搭配菠萝独有的酸酸甜甜的味道，真的是升华了整道炒饭的口感！而且这道菜营养均衡，有 ...', '在泰国必吃的11道美味泰国菜 · 1.冬阴功汤 · 2.青木瓜沙拉 · 3.泰国娘惹咖喱酱 · 4.泰式炒河粉 · 5.Pad Kra Pow Gai · 6.菠萝泰式炒饭 · 7.绿咖喱 · 8.辣牛肉沙律.', '青木瓜沙拉(ส้มตำ) · 泰式柚子沙拉(ยำส้มโอ) · 泰式春卷(ปอเปี๊ยะสด) · 清汤冬阴功(ต้มยำกุ้งน้ำใส) · 海南鸡饭(ข้าวมันไก่) · 柠檬蒸鲈鱼(ปลากะพงนึ่งมะนาว) · 泰式椰汁煮 ...', '大家喜爱的泰国菜有冬阴功汤，Pad Thai， 青木瓜色拉，咖喱等。洛杉矶这里的泰国菜种类主要有两种；一种是地道的泰式风味，另一种则是亚洲融合菜。比如 ...', '同样是泰国代表菜的木瓜沙拉，发源于泰国东北，老挝等地。 决定一份木瓜沙拉的好坏主要是木瓜的新鲜程度，甜度，辣椒的辣度和盐的比例。 味道非常爽口，是解腻良菜。 重点推荐。', '10道必尝的泰国菜 · Larb Moo · Phad Thai · Khao Soi · Kra Pao Moo Krob · Som Tam · Gai Pad Med Ma Muang · Hor Mok Pla ...', \"9家纽约必吃泰国菜 · Thai Villa · Fish Cheeks · LumLum · Up Thai · Wayla · Soothr's · The Tyger · Thai Diner.\", '去泰国餐厅10大必点菜! · 一、青木瓜色拉. 很多人都超级爱青木瓜色拉的酸辣爽脆，凉拌青木瓜色拉，不仅保留了青木瓜的原始营养状态，加入了青瓜丝的清新， ...', '曼谷當地必吃美食 · 辣蝦湯 · 辣味青木瓜沙拉 · 椰子燉雞湯 · 紅咖哩 · 泰式炒河粉 · 泰式炒飯 · 打拋豬肉 · 綠咖哩雞 ...', '米其林评审员的评语：对我来说，这是泰国最好的鱼肉冬阴汤。厨师找到了很好的味道平衡：酸、咸、辣和最后的一点点甜味。所有的味道都与鱼肉都搭配得很好， ...']\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m```json\n",
      "{\n",
      "    \"action\": \"Final Answer\",\n",
      "    \"action_input\": \"泰国菜中有许多美味的选择。比如菠萝炒饭，它将泰国香米的香气与菠萝的酸甜味道完美结合，营养均衡。其他推荐的泰国菜包括冬阴功汤、青木瓜沙拉、泰式炒河粉、Pad Kra Pow Gai（罗勒炒鸡）、绿咖喱、辣牛肉沙律等。这些菜肴不仅味道丰富，而且色香味俱佳，值得尝试。\"\n",
      "}\n",
      "```\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'泰国菜中有许多美味的选择。比如菠萝炒饭，它将泰国香米的香气与菠萝的酸甜味道完美结合，营养均衡。其他推荐的泰国菜包括冬阴功汤、青木瓜沙拉、泰式炒河粉、Pad Kra Pow Gai（罗勒炒鸡）、绿咖喱、辣牛肉沙律等。这些菜肴不仅味道丰富，而且色香味俱佳，值得尝试。'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(input=\"有什么好吃的泰国菜给我推荐一下？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m```json\n",
      "{\n",
      "    \"action\": \"Search\",\n",
      "    \"action_input\": \"1998年世界杯冠军\"\n",
      "}\n",
      "```\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3mFrance national football team\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m```json\n",
      "{\n",
      "    \"action\": \"Final Answer\",\n",
      "    \"action_input\": \"你名字的最后一个字母是 Y。1998年的世界杯冠军是法国国家足球队。\"\n",
      "}\n",
      "```\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'你名字的最后一个字母是 Y。1998年的世界杯冠军是法国国家足球队。'"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(input=\"我都没吃过！我名字的最后一个字母是什么？1998年的世界杯谁夺冠了？\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "OPENAI_FUNCTIONS，使用openai的函数调用来实现的，只支持openai模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "memory=ConversationBufferMemory(return_messages=True, memory_key='chat_history') verbose=True tags=['openai-functions'] agent=OpenAIFunctionsAgent(llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1'), tools=[Tool(name='Search', description='A search engine. Useful for when you need to answer questions about current events. Input should be a search query.', func=<bound method SerpAPIWrapper.run of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>, coroutine=<bound method SerpAPIWrapper.arun of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>), Tool(name='Calculator', description='Useful for when you need to answer questions about math.', func=<bound method Chain.run of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>, coroutine=<bound method Chain.arun of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>)], prompt=ChatPromptTemplate(input_variables=['agent_scratchpad', 'input'], input_types={'agent_scratchpad': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]]}, messages=[SystemMessage(content='You are a helpful AI assistant.'), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), MessagesPlaceholder(variable_name='agent_scratchpad')])) tools=[Tool(name='Search', description='A search engine. Useful for when you need to answer questions about current events. Input should be a search query.', func=<bound method SerpAPIWrapper.run of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>, coroutine=<bound method SerpAPIWrapper.arun of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>), Tool(name='Calculator', description='Useful for when you need to answer questions about math.', func=<bound method Chain.run of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>, coroutine=<bound method Chain.arun of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>)]\n",
      "[SystemMessage(content='You are a helpful AI assistant.'), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), MessagesPlaceholder(variable_name='agent_scratchpad')]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/tomiezhang/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:115: LangChainDeprecationWarning: The class `ChatOpenAI` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use langchain_openai.ChatOpenAI instead.\n",
      "  warn_deprecated(\n",
      "/Users/tomiezhang/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:115: LangChainDeprecationWarning: The function `initialize_agent` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use Use new agent constructor methods like create_react_agent, create_json_agent, create_structured_chat_agent, etc. instead.\n",
      "  warn_deprecated(\n"
     ]
    }
   ],
   "source": [
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.agents import (\n",
    "    load_tools,\n",
    "    initialize_agent,\n",
    "    AgentType,\n",
    ")\n",
    "from langchain.memory import ConversationBufferMemory\n",
    "import os\n",
    "os.environ[\"SERPAPI_API_KEY\"] = \"f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594\"\n",
    "#记忆组件\n",
    "memory = ConversationBufferMemory(\n",
    "    memory_key=\"chat_history\",\n",
    "    return_messages=True,\n",
    ")\n",
    "\n",
    "llm = ChatOpenAI(\n",
    "    temperature=0,\n",
    "    model=\"gpt-4-1106-preview\",\n",
    ")\n",
    "tools = load_tools([\"serpapi\",\"llm-math\"],llm=llm)\n",
    "agent = initialize_agent(\n",
    "    tools,\n",
    "    llm,\n",
    "    agent=AgentType.OPENAI_FUNCTIONS,\n",
    "    memory=memory,#记忆组件\n",
    "    verbose=True,\n",
    ")\n",
    "print(agent)\n",
    "print(agent.agent.prompt.messages)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/tomiezhang/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:115: LangChainDeprecationWarning: The function `run` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use invoke instead.\n",
      "  warn_deprecated(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `Search` with `\n",
      "Bitcoin price today`\n",
      "\n",
      "\n",
      "\u001b[0m\u001b[36;1m\u001b[1;3m42,449.40\u001b[0m\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `Calculator` with `sqrt(42449.40)`\n",
      "\n",
      "\n",
      "\u001b[0m\u001b[33;1m\u001b[1;3mAnswer: 206.03252170470563\u001b[0m\u001b[32;1m\u001b[1;3m今天比特币的价格是 $42,449.40。它的价格开平方后大约是 $206.03。\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'今天比特币的价格是 $42,449.40。它的价格开平方后大约是 $206.03。'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.run(input=\"今天比特币的价格是多少？它的价格开平方是多少？\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION 对输出做了结构化处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "memory=ConversationBufferMemory(return_messages=True, memory_key='chat_history') verbose=True tags=['structured-chat-zero-shot-react-description'] agent=StructuredChatAgent(llm_chain=LLMChain(prompt=ChatPromptTemplate(input_variables=['agent_scratchpad', 'input'], messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='Respond to the human as helpfully and accurately as possible. You have access to the following tools:\\n\\nSearch: A search engine. Useful for when you need to answer questions about current events. Input should be a search query., args: {{\\'tool_input\\': {{\\'type\\': \\'string\\'}}}}\\nCalculator: Useful for when you need to answer questions about math., args: {{\\'tool_input\\': {{\\'type\\': \\'string\\'}}}}\\n\\nUse a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input).\\n\\nValid \"action\" values: \"Final Answer\" or Search, Calculator\\n\\nProvide only ONE action per $JSON_BLOB, as shown:\\n\\n```\\n{{\\n  \"action\": $TOOL_NAME,\\n  \"action_input\": $INPUT\\n}}\\n```\\n\\nFollow this format:\\n\\nQuestion: input question to answer\\nThought: consider previous and subsequent steps\\nAction:\\n```\\n$JSON_BLOB\\n```\\nObservation: action result\\n... (repeat Thought/Action/Observation N times)\\nThought: I know what to respond\\nAction:\\n```\\n{{\\n  \"action\": \"Final Answer\",\\n  \"action_input\": \"Final response to human\"\\n}}\\n```\\n\\nBegin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:.\\nThought:')), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['agent_scratchpad', 'input'], template='{input}\\n\\n{agent_scratchpad}'))]), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')), output_parser=StructuredChatOutputParserWithRetries(output_fixing_parser=OutputFixingParser(parser=StructuredChatOutputParser(), retry_chain=LLMChain(prompt=PromptTemplate(input_variables=['completion', 'error', 'instructions'], template='Instructions:\\n--------------\\n{instructions}\\n--------------\\nCompletion:\\n--------------\\n{completion}\\n--------------\\n\\nAbove, the Completion did not satisfy the constraints given in the Instructions.\\nError:\\n--------------\\n{error}\\n--------------\\n\\nPlease try again. Please only respond with an answer that satisfies the constraints laid out in the Instructions:'), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))), allowed_tools=['Search', 'Calculator']) tools=[Tool(name='Search', description='A search engine. Useful for when you need to answer questions about current events. Input should be a search query.', func=<bound method SerpAPIWrapper.run of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>, coroutine=<bound method SerpAPIWrapper.arun of SerpAPIWrapper(search_engine=<class 'serpapi.google_search.GoogleSearch'>, params={'engine': 'google', 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'}, serpapi_api_key='f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594', aiosession=None)>), Tool(name='Calculator', description='Useful for when you need to answer questions about math.', func=<bound method Chain.run of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>, coroutine=<bound method Chain.arun of LLMMathChain(llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['question'], template='Translate a math problem into a expression that can be executed using Python\\'s numexpr library. Use the output of running this code to answer the question.\\n\\nQuestion: ${{Question with math problem.}}\\n```text\\n${{single line mathematical expression that solves the problem}}\\n```\\n...numexpr.evaluate(text)...\\n```output\\n${{Output of running the code}}\\n```\\nAnswer: ${{Answer}}\\n\\nBegin.\\n\\nQuestion: What is 37593 * 67?\\n```text\\n37593 * 67\\n```\\n...numexpr.evaluate(\"37593 * 67\")...\\n```output\\n2518731\\n```\\nAnswer: 2518731\\n\\nQuestion: 37593^(1/5)\\n```text\\n37593**(1/5)\\n```\\n...numexpr.evaluate(\"37593**(1/5)\")...\\n```output\\n8.222831614237718\\n```\\nAnswer: 8.222831614237718\\n\\nQuestion: {question}\\n'), llm=ChatOpenAI(client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-4-1106-preview', temperature=0.0, openai_api_key='sk-9npZpELUzM0IxRU1B79bF5B9FfC04bDeA730F4090dF782A3', openai_api_base='https://ai-yyds.com/v1', openai_proxy='https://ai-yyds.com/v1')))>)] handle_parsing_errors=True\n",
      "Respond to the human as helpfully and accurately as possible. You have access to the following tools:\n",
      "\n",
      "Search: A search engine. Useful for when you need to answer questions about current events. Input should be a search query., args: {{'tool_input': {{'type': 'string'}}}}\n",
      "Calculator: Useful for when you need to answer questions about math., args: {{'tool_input': {{'type': 'string'}}}}\n",
      "\n",
      "Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input).\n",
      "\n",
      "Valid \"action\" values: \"Final Answer\" or Search, Calculator\n",
      "\n",
      "Provide only ONE action per $JSON_BLOB, as shown:\n",
      "\n",
      "```\n",
      "{{\n",
      "  \"action\": $TOOL_NAME,\n",
      "  \"action_input\": $INPUT\n",
      "}}\n",
      "```\n",
      "\n",
      "Follow this format:\n",
      "\n",
      "Question: input question to answer\n",
      "Thought: consider previous and subsequent steps\n",
      "Action:\n",
      "```\n",
      "$JSON_BLOB\n",
      "```\n",
      "Observation: action result\n",
      "... (repeat Thought/Action/Observation N times)\n",
      "Thought: I know what to respond\n",
      "Action:\n",
      "```\n",
      "{{\n",
      "  \"action\": \"Final Answer\",\n",
      "  \"action_input\": \"Final response to human\"\n",
      "}}\n",
      "```\n",
      "\n",
      "Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:.\n",
      "Thought:\n",
      "{input}\n",
      "\n",
      "{agent_scratchpad}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/tomiezhang/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:115: LangChainDeprecationWarning: The class `ChatOpenAI` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use langchain_openai.ChatOpenAI instead.\n",
      "  warn_deprecated(\n",
      "/Users/tomiezhang/.pyenv/versions/3.10.12/envs/langchains/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:115: LangChainDeprecationWarning: The function `initialize_agent` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use Use new agent constructor methods like create_react_agent, create_json_agent, create_structured_chat_agent, etc. instead.\n",
      "  warn_deprecated(\n"
     ]
    }
   ],
   "source": [
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.agents import (\n",
    "    load_tools,\n",
    "    initialize_agent,\n",
    "    AgentType,\n",
    ")\n",
    "from langchain.memory import ConversationBufferMemory\n",
    "import os\n",
    "os.environ[\"SERPAPI_API_KEY\"] = \"f265b8d9834ed7692cba6db6618e2a8a9b24ed6964c457296a2626026e8ed594\"\n",
    "#记忆组件\n",
    "memory = ConversationBufferMemory(\n",
    "    memory_key=\"chat_history\",\n",
    "    return_messages=True,\n",
    ")\n",
    "\n",
    "llm = ChatOpenAI(\n",
    "    temperature=0,\n",
    "    model=\"gpt-4-1106-preview\",\n",
    ")\n",
    "tools = load_tools([\"serpapi\",\"llm-math\"],llm=llm)\n",
    "agent = initialize_agent(\n",
    "    tools,\n",
    "    llm,\n",
    "    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
    "    memory=memory,#记忆组件\n",
    "    handle_parsing_errors=True,\n",
    "    verbose=True,\n",
    ")\n",
    "print(agent)\n",
    "print(agent.agent.llm_chain.prompt.messages[0].prompt.template)\n",
    "print(agent.agent.llm_chain.prompt.messages[1].prompt.template)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3mThought: Langchain is not a widely recognized term that I am familiar with, and it may refer to a specific product, service, or concept that has emerged after my last update. I will use the search tool to find the most current information on \"langchain.\"\n",
      "\n",
      "Action:\n",
      "```\n",
      "{\n",
      "  \"action\": \"Search\",\n",
      "  \"action_input\": {\"type\": \"langchain\"}\n",
      "}\n",
      "```\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m[\"LangChain is a framework designed to simplify the creation of applications using large language models. As a language model integration framework, LangChain's use-cases largely overlap with those of language models in general, including document analysis and summarization, chatbots, and code analysis.\", 'LangChain initial_release_date: October 2022.', 'LangChain developer_s: Harrison Chase.', 'LangChain license: MIT License.', 'LangChain stable_release: 0.0.351 / 18 December 2023; 26 days ago.', 'LangChain written_in: Python and JavaScript.', 'https://www.langchain.com/', 'https://github.com/langchain-ai/langchain', 'https://en.wikipedia.org/wiki/LangChain', 'https://www.ibm.com/topics/langchain', 'https://aws.amazon.com/what-is/langchain/', 'https://www.techtarget.com/searchenterpriseai/definition/LangChain', 'https://blog.langchain.dev/langchain-v0-1-0/']\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3mThe search results provided a clear definition and details about LangChain. It is a framework designed to facilitate the creation of applications that utilize large language models. It can be used for various purposes such as document analysis, summarization, chatbots, and code analysis. The initial release date of LangChain was in October 2022, and it was developed by Harrison Chase. It is licensed under the MIT License and the stable release version as of the last update was 0.0.351, which was released on December 18, 2023. LangChain is written in Python and JavaScript. There are also several links provided, including the official website, GitHub repository, and additional resources.\n",
      "\n",
      "Action:\n",
      "```\n",
      "{\n",
      "  \"action\": \"Final Answer\",\n",
      "  \"action_input\": \"LangChain is a framework designed to simplify the creation of applications using large language models. It is used for tasks like document analysis, summarization, chatbots, and code analysis. LangChain was initially released in October 2022 by developer Harrison Chase and is licensed under the MIT License. The latest stable release is version 0.0.351, which came out on December 18, 2023. It is written in Python and JavaScript. For more information, you can visit the official website at www.langchain.com or its GitHub repository at github.com/langchain-ai/langchain.\"\n",
      "}\n",
      "```\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': 'what is langchain?',\n",
       " 'chat_history': [HumanMessage(content='what is langchain?'),\n",
       "  AIMessage(content='LangChain is a framework designed to simplify the creation of applications using large language models. It is used for tasks like document analysis, summarization, chatbots, and code analysis. LangChain was initially released in October 2022 by developer Harrison Chase and is licensed under the MIT License. The latest stable release is version 0.0.351, which came out on December 18, 2023. It is written in Python and JavaScript. For more information, you can visit the official website at www.langchain.com or its GitHub repository at github.com/langchain-ai/langchain.')],\n",
       " 'output': 'LangChain is a framework designed to simplify the creation of applications using large language models. It is used for tasks like document analysis, summarization, chatbots, and code analysis. LangChain was initially released in October 2022 by developer Harrison Chase and is licensed under the MIT License. The latest stable release is version 0.0.351, which came out on December 18, 2023. It is written in Python and JavaScript. For more information, you can visit the official website at www.langchain.com or its GitHub repository at github.com/langchain-ai/langchain.'}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.invoke({\"input\":\"what is langchain?\"})"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchains",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
      